package com.doublethread.easymart.common.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.doublethread.easymart.common.exception.FileException;
import com.doublethread.easymart.config.OssConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * OSS图片上传工具类
 */
@Slf4j
@Component
public class OssUtils {

    @Autowired
    private OSS ossClient;

    @Autowired
    private OssConfig ossConfig;

    /**
     * 上传图片文件
     */
    public String uploadImage(MultipartFile file) {
        return uploadImage(file, ossConfig.getImagePath());
    }

    /**
     * 上传图片文件到指定路径
     */
    public String uploadImage(MultipartFile file, String customPath) {
        // 检查文件是否合法
        checkFile(file);

        // 生成唯一的文件名
        String fileName = createFileName(file.getOriginalFilename());

        // 构建在OSS中的完整路径
        String filePath = customPath + fileName;

        try {
            // 上传文件到OSS
            uploadToOss(file, filePath);

            // 生成访问URL
            String imageUrl = createImageUrl(filePath);

            log.info("图片上传成功");
            return imageUrl;

        } catch (IOException e) {
            log.error("图片上传失败", e);
            FileException.uploadFailed();
            return null;
        }
    }

    /**
     * 删除图片文件
     * 根据图片URL删除OSS中的文件
     *
     * @param imageUrl 图片URL
     */
    public void deleteImage(String imageUrl) {
        if (imageUrl == null || imageUrl.isEmpty()) {
            return;
        }

        try {
            // 从URL中提取文件路径
            String filePath = getFilePathFromUrl(imageUrl);
            if (filePath != null) {
                ossClient.deleteObject(ossConfig.getBucketName(), filePath);
                log.info("图片删除成功: {}", imageUrl);
            }
        } catch (Exception e) {
            log.error("图片删除失败: {}", e.getMessage(), e);
            // 删除失败不抛异常，避免影响主业务
        }
    }

    /**
     * 检查文件是否合法
     */
    private void checkFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            log.error("上传文件为空");
            FileException.uploadFailed();
            return;
        }

        if (file.getSize() > ossConfig.getMaxFileSizeBytes()) {
            log.error("文件大小超出限制");
            FileException.sizeExceeded();
        }

        String fileName = file.getOriginalFilename();
        if (fileName == null || !isImageFile(fileName)) {
            log.error("文件格式不支持");
            FileException.typeNotAllowed();
        }
    }

    /**
     * 检查是否为图片文件
     */
    private boolean isImageFile(String fileName) {
        String extension = getFileExtension(fileName);
        return ossConfig.getAllowedFormatList().contains(extension.toLowerCase());
    }

    /**
     * 获取文件扩展名
     * 从文件名中提取扩展名
     */
    private String getFileExtension(String fileName) {
        int lastDot = fileName.lastIndexOf(".");
        if (lastDot > 0 && lastDot < fileName.length() - 1) {
            return fileName.substring(lastDot + 1);
        }
        return "";
    }

    /**
     * 创建唯一的文件名
     * 格式：年/月/日/UUID.扩展名
     */
    private String createFileName(String originalFileName) {
        String extension = getFileExtension(originalFileName);
        String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return datePath + "/" + uuid + "." + extension;
    }

    /**
     * 上传文件到OSS
     */
    private void uploadToOss(MultipartFile file, String filePath) throws IOException {
        // 设置文件元数据
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentLength(file.getSize());
        metadata.setContentType(file.getContentType());
        metadata.setCacheControl("max-age=31536000"); // 缓存一年

        // 创建上传请求
        PutObjectRequest request = new PutObjectRequest(
                ossConfig.getBucketName(),
                filePath,
                file.getInputStream(),
                metadata
        );

        // 执行上传
        ossClient.putObject(request);
    }

    /**
     * 创建图片访问URL
     */
    private String createImageUrl(String filePath) {
        return "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/" + filePath;
    }

    /**
     * 从URL中提取文件路径
     * 用于删除文件时获取OSS中的文件路径
     */
    private String getFilePathFromUrl(String imageUrl) {
        try {
            String urlPrefix = "https://" + ossConfig.getBucketName() + "." + ossConfig.getEndpoint() + "/";
            if (imageUrl.startsWith(urlPrefix)) {
                return imageUrl.substring(urlPrefix.length());
            }
        } catch (Exception e) {
            log.warn("无法从URL提取文件路径: {}", imageUrl);
        }
        return null;
    }
}
